#example 1
class myClass(object):
    
     def __init__(self):
         self.foo = 100

myInst = myClass()
print hasattr(myInst, 'foo')
print getattr(myInst, 'foo')
print hasattr(myInst, 'bar')

#print getattr(myInst, 'bar')
print getattr(myInst, 'bar', 'oops!')

setattr(myInst, 'bar', 'my attr')

print myInst.__dict__
print getattr(myInst, 'bar')

delattr(myInst, 'foo')

print dir(myInst)
print hasattr(myInst, 'foo')

#example 2
print "###############################EXAMPLE 2########################"

class myClass_2(object):
    
     def __init__(self):
         self.foo = 100

     def __getattr__(self, name):
         print "gettAttr"
         #ERROR! CYCLIC
         #return self.name

myInst2 = myClass_2()
#exist
myInst2.foo
#if argument not Exist call __getattr__
#not exist
getattr(myInst2, "no_argument")
myInst2.__getattr__("no_argument")
myInst2.no_argument

#example 3
print "###############################EXAMPLE 3########################"

class myClass_3(object):
    
     def __init__(self):
         self.foo  = 100

     def __getattribute__(self,name):

        print "=>" + name
          
        if name == "foo":

             #TypeError: 'int' object is not callable
             #because self.0 (self, name) !!! or #TypeError: 'str'
             #self.'str'(self, name)
             return object.__getattribute__(self, name)
             
        else:
            return 0
  
myInst3 = myClass_3()
#__getAttribute__ call if argument exist or not it doesnt matter!
#exist
print myInst3.foo
#not exist
myInst3.no_argument




